/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cmp.player.controls;

import static com.cmp.core.constants.InputUIDConstants.*;
import static com.cmp.core.constants.PlayerStateUIDConstants.*;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;

/**
 * Allows the node to move. Requires physics.
 * @author krummer
 */
public class MoveControl extends AbstractControl {
    
    private boolean isUp, isDown, isLeft, isRight;
    private static final String ROOT_KEY = "moveRoot";
    private float rootDuration;
    
    private CharacterRigidBodyControl body;
    
    @Override
    public void setSpatial(Spatial spatial) {
        super.setSpatial(spatial);
        
        //set shortcut to body
        //TODO: check if it has a body. If not make other movement?
        body = this.getSpatial().getControl(CharacterRigidBodyControl.class);
        
        //cache directional commands and everything
        this.setRooted(false, 0.f);
        spatial.setUserData(UP_BUTTON_UID, false);
        spatial.setUserData(DOWN_BUTTON_UID, false);
        spatial.setUserData(LEFT_BUTTON_UID, false);
        spatial.setUserData(RIGHT_BUTTON_UID, false);
        this.setMoveSpeed(10.f);
        
    }
    
    /**
     * looks for directional commands and 
     * calculates the direction vector.
     */
    public Vector3f calcMoveDir() {
        //get action states
        isUp = getSpatial().getUserData(UP_BUTTON_UID);
        isDown = getSpatial().getUserData(DOWN_BUTTON_UID);
        isLeft = getSpatial().getUserData(LEFT_BUTTON_UID);
        isRight = getSpatial().getUserData(RIGHT_BUTTON_UID);
        
        Vector3f walkdir = Vector3f.ZERO;
        //calculate direction from buttons.
        if (isUp) {
            walkdir = walkdir.add(new Vector3f(0, 0, 1));
        }
        if (isDown) {
            walkdir = walkdir.add(new Vector3f(0, 0, -1));
        }
        if (isLeft) {
            walkdir = walkdir.add(new Vector3f(1, 0, 0));
        }
        if (isRight) {
            walkdir = walkdir.add(new Vector3f(-1, 0, 0));
        }
        
        return walkdir.normalize();
    }
    
    public void setMoveSpeed(float speed) {
        super.getSpatial().setUserData(MOVESPEED_VALUE_UID, speed);
    }
    
    public float getMoveSpeed() {
        return super.getSpatial().getUserData(MOVESPEED_VALUE_UID);
    }
    
    /**
     * lock/unlock movements
     * @param root is locked ?
     */
    public void setRooted(boolean root, float duration) {
        
        this.getSpatial().setUserData(ROOT_KEY, root);
        this.rootDuration = duration;
    }
    
    public boolean isRooted() {
        return this.getSpatial().getUserData(ROOT_KEY);
    }
    /**
     * take a step.
     */
    public void move() {
        // don't mess with the jump!
        Vector3f moveSpeed = calcMoveDir().mult(this.getMoveSpeed());
        moveSpeed.setY(body.getLinearVelocity().y);
        this.body.setLinearVelocity(moveSpeed);
    }
    
    @Override
    protected void controlUpdate(float tpf) {
        if(!this.isRooted()) {
            
            //this.calcMoveDir();
            this.move();
        }  else {
            this.rootDuration -= tpf;
            if(this.rootDuration < 0.f) {
                this.rootDuration = 0.f;
                this.setRooted(false, 0f);
            }
        }
        
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {

    }

    public Control cloneForSpatial(Spatial spatial) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
}
